#include <QCoreApplication>
#include <QUdpSocket>
#include <QNetworkInterface>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QUdpSocket *udpSocket = new QUdpSocket();

    // 配置组播地址和端口
    QHostAddress groupAddress("225.1.1.1");
    quint16 groupPort = 1688;

    // 查找指定名称的网卡接口
    QNetworkInterface targetInterface;
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    for (const QNetworkInterface &interface : interfaces) {
        if (interface.humanReadableName() == "wlaaaaa") { // 请替换为你的网卡名称
            targetInterface = interface;
            qDebug() << "找到目标网卡:" << interface.humanReadableName() << "(" << interface.name() << ")";
            break;
        }
    }

    if (!targetInterface.isValid()) {
        qDebug() << "未找到指定名称的网卡，使用默认网卡。";
        // 如果找不到指定网卡，可以在此选择其他策略，例如使用默认接口或退出
        // return -1; 
    }

    // 绑定到本地端口 (可选择绑定到目标接口的IP地址)
    // 如果需要严格绑定到目标网卡的IP，可以先获取该接口的IP地址列表
    // QList<QNetworkAddressEntry> entries = targetInterface.addressEntries();
    // 然后选择一个IPv4地址进行绑定
    if (!udpSocket->bind(QHostAddress::AnyIPv4, groupPort, QUdpSocket::ShareAddress)) {
        qDebug() << "绑定端口失败!";
        return -1;
    }

    // 方法1：加入组播组时指定接口（推荐）
    if (!udpSocket->joinMulticastGroup(groupAddress, targetInterface)) {
        qDebug() << "加入组播组失败!";
        // 可以考虑尝试使用默认接口加入
        // if (!udpSocket->joinMulticastGroup(groupAddress)) {
        //     qDebug() << "使用默认接口加入组播组也失败!";
        //     return -1;
        // }
    } else {
        qDebug() << "使用方法1（joinMulticastGroup指定接口）成功加入组播。";
    }

    // 方法2：设置组播接口（在某些情况下可能需要）
    // udpSocket->setMulticastInterface(targetInterface);

    // 连接信号槽处理接收数据
    QObject::connect(udpSocket, &QUdpSocket::readyRead, [&]() {
        while (udpSocket->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(udpSocket->pendingDatagramSize());
            
            QHostAddress senderAddress;
            quint16 senderPort;
            
            qint64 bytesRead = udpSocket->readDatagram(datagram.data(), datagram.size(), &senderAddress, &senderPort);

            if (bytesRead > 0) {
                qDebug() << "接收数据长度:" << bytesRead << "字节";
                qDebug() << "发送方IP:" << senderAddress.toString();
                qDebug() << "发送方端口:" << senderPort;
                // 如果还需要打印数据内容，可以取消下一行的注释
                // qDebug() << "数据内容 (十六进制):" << datagram.toHex();
                qDebug() << "----------------------------------------";
            }
        }
    });

    qDebug() << "组播监听已启动，组播地址:" << groupAddress.toString() << "端口:" << groupPort;

    return a.exec();
}

/*
#include <QNetworkDatagram>
#include <QNetworkInterface>
#include <QSettings>
#include <QTimer>
#include <QUdpSocket>
#include <QCoreApplication>

int main(int argc, char **argv)
{
	QCoreApplication a(argc, argv);
	QSettings settings("multicast.conf", QSettings::IniFormat);
	settings.beginGroup("Multicast");
	QString strLocalIP = settings.value("LocalIP", "127.0.0.1").toString();
	QString strGroup = settings.value("Group", "234.5.6.7").toString();
	short nPort = settings.value("Port", 1234).toInt();
	short nPeerPort = settings.value("PeerPort", 1235).toInt();
	settings.endGroup();

	int i, j, nIndex = 0, nIdx = 0;
	const QList<QNetworkInterface> &lni = QNetworkInterface::allInterfaces();
	for (i = 0; i < lni.size(); i++)
	{
		bool bFind = false;
		const QList<QNetworkAddressEntry> &nae = lni[i].addressEntries();
		for (j = nae.size() - 1; j >= 0; j--)
		{
			printf("%s\n", nae[j].ip().toString().toLatin1().data());
			if (nae[j].ip().toString() == strLocalIP)
			{
                nIdx = j;
				bFind = true;
				break;
			}
		}
		if (bFind)
		{
			nIndex = i;
			break;
		}
	}
    
	printf("Multicast:%s\tPort:%d\tPeerPort:%d\tLocalIP:%s\n",
		   strGroup.toLatin1().data(), nPort, nPeerPort,
		   strLocalIP.toLatin1().data());


	QHostAddress groupAddr(strGroup);
	QUdpSocket udp;
	const QNetworkInterface &ni = lni[nIndex];
    //必须绑定QHostAddress::AnyIPv4，否则无法接收到组播和广播报文，只能接收到发送给特定IP地址的报文
	//bool b = udp.bind(ni.addressEntries()[nIdx].ip(), nPort, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
    bool b = udp.bind(QHostAddress::AnyIPv4, nPort, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
	udp.setSocketOption(QAbstractSocket::MulticastLoopbackOption, 1);
	// 多网卡时为了能够建立正确的组播路由，必须先设置组播网卡setMulticastInterface，再加入组播组joinMulticastGroup，
	// 并且加入组播的同时指定网卡joinMulticastGroup(groupAddr, lni[nIndex])
	//udp.setMulticastInterface(ni);
	b = udp.joinMulticastGroup(groupAddr, ni);
	b = QObject::connect(&udp, &QUdpSocket::readyRead, [&udp]()
    {
		if (udp.hasPendingDatagrams())
		{
			const QNetworkDatagram &nd = udp.receiveDatagram();
			const QByteArray &ba = nd.data();
			printf("recv,%s:%d,%d\n", nd.senderAddress().toString().toLatin1().data(), nd.senderPort(), ba.size());
		}
	});

    QTimer timer;
    QNetworkDatagram datagram;
    datagram.setDestination(groupAddr, nPort);
    QObject::connect(&timer, &QTimer::timeout, [&udp, &datagram]()
    {
        char szT[16];
        static int i =0;
        sprintf(szT, "s:%d", i++);
		datagram.setData(szT);
		int n = udp.writeDatagram(datagram);
    });
    timer.start(1000);

	return a.exec();
}
//*/

/*
#include <QCoreApplication>
#include <QUdpSocket>
#include <QNetworkInterface>
#include <QDebug>
#include <QThread>

// 组播地址和端口
const QHostAddress MULTICAST_ADDR("239.255.43.21");
const quint16 PORT = 45454;

// 获取有效网卡列表
QList<QNetworkInterface> getValidInterfaces() {
    QList<QNetworkInterface> validInterfaces;
    foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
        if (interface.flags() & QNetworkInterface::IsUp &&
            interface.flags() & QNetworkInterface::IsRunning &&
            interface.flags() & QNetworkInterface::CanMulticast) {
            validInterfaces.append(interface);
        }
    }
    return validInterfaces;
}

// 接收组播数据（多网卡）
void setupMulticastReceivers() {
    foreach (const QNetworkInterface &interface, getValidInterfaces()) {
        QUdpSocket *socket = new QUdpSocket;
        
        // 绑定到网卡的具体IP地址
        foreach (const QNetworkAddressEntry &entry, interface.addressEntries()) {
            if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
                if (socket->bind(entry.ip(), PORT, QUdpSocket::ShareAddress)) {
                    // 加入组播组并指定网卡
                    if (socket->joinMulticastGroup(MULTICAST_ADDR, interface)) {
                        qDebug() << "Joined multicast on" << interface.name() << entry.ip().toString();
                        QObject::connect(socket, &QUdpSocket::readyRead, [socket]() {
                            while (socket->hasPendingDatagrams()) {
                                QByteArray data;
                                data.resize(socket->pendingDatagramSize());
                                QHostAddress sender;
                                quint16 senderPort;
                                socket->readDatagram(data.data(), data.size(), &sender, &senderPort);
                                qDebug() << "Received from" << sender << "on" << socket->localAddress() << ":" << data;
                            }
                        });
                    } else {
                        qWarning() << "Join failed on" << interface.name();
                    }
                    break; // 使用该网卡第一个有效IP
                }
            }
        }
    }
}

// 发送组播数据（指定出口网卡）
void sendMulticast(const QNetworkInterface &interface, const QByteArray &data) {
    QUdpSocket socket;
    
    // 绑定到网卡的具体IP（非0.0.0.0）
    foreach (const QNetworkAddressEntry &entry, interface.addressEntries()) {
        if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol) {
            if (socket.bind(entry.ip(), 0)) { // 端口0表示自动分配
                qint64 sent = socket.writeDatagram(data, MULTICAST_ADDR, PORT);
                if (sent > 0) {
                    qDebug() << "Sent from" << entry.ip().toString();
                }
                break;
            }
        }
    }
}

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    
    setupMulticastReceivers();
    
    // 示例：通过第一个有效网卡发送测试数据
    auto interfaces = getValidInterfaces();
    if (!interfaces.isEmpty())
	{
		for(int i = 0; i <1000; i++)
		{
			sendMulticast(interfaces.first(), "Hello Multicast!");
			QThread::sleep(1);
		}
     }
    
    return a.exec();
}
//*/

/*
#include <QCoreApplication>
#include <QUdpSocket>
#include <QNetworkInterface>
#include <QNetworkProxy>
#include <QDebug>
#include <QTimer>

const QHostAddress MULTICAST_ADDR("239.255.43.21");
const quint16 PORT = 45454;

// 增强版：获取有效网卡列表
QList<QNetworkInterface> getValidInterfaces() {
    QList<QNetworkInterface> validInterfaces;
    foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
        // 添加更详细的过滤条件
        bool isLoopback = interface.flags() & QNetworkInterface::IsLoopBack;
        bool hasIPv4 = false;
        
        // 检查是否有IPv4地址
        foreach (const QNetworkAddressEntry &entry, interface.addressEntries()) {
            if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && !entry.ip().isNull()) {
                hasIPv4 = true;
                break;
            }
        }
        
        // 关键修改：调整网卡过滤条件
        if (interface.isValid() && 
            !isLoopback &&
            hasIPv4 &&
            interface.flags().testFlag(QNetworkInterface::IsUp) &&
            interface.flags().testFlag(QNetworkInterface::IsRunning) &&
            interface.flags().testFlag(QNetworkInterface::CanMulticast)) 
        {
            qDebug() << "Valid interface:" << interface.name() 
                     << "| HW Addr:" << interface.hardwareAddress()
                     << "| Index:" << interface.index();
            validInterfaces.append(interface);
        }
    }
    return validInterfaces;
}

// 接收组播数据（修复版）
void setupMulticastReceivers() {
    foreach (const QNetworkInterface &interface, getValidInterfaces()) {
        QUdpSocket *socket = new QUdpSocket;
        
        // 关键修复：明确设置代理为无代理
        socket->setProxy(QNetworkProxy::NoProxy);
        
        // 绑定到网卡的具体IPv4地址
        foreach (const QNetworkAddressEntry &entry, interface.addressEntries()) {
            QHostAddress ip = entry.ip();
            if (ip.protocol() == QAbstractSocket::IPv4Protocol && !ip.isNull()) {
                qDebug() << "Trying to bind on" << interface.name() << "| IP:" << ip.toString();
                
                // 关键修改：使用ReuseAddressHint选项
                if (socket->bind(ip, PORT, QUdpSocket::ReuseAddressHint | QUdpSocket::ShareAddress)) {
                    qDebug() << "Bound successfully on" << interface.name();
                    
                    // 关键修改：使用两种方式加入组播组
                    bool joinSuccess = false;
                    
                    // 方法1：使用网卡对象加入
                    if (socket->joinMulticastGroup(MULTICAST_ADDR, interface)) {
                        joinSuccess = true;
                    } 
                    // 方法2：回退方案 - 使用IP地址加入
                    else if (socket->joinMulticastGroup(MULTICAST_ADDR)) {
                        qWarning() << "Joined without interface on" << interface.name();
                        joinSuccess = true;
                    }
                    
                    if (joinSuccess) {
                        qDebug() << "Joined multicast group on" << interface.name();
                        
                        // 连接信号
                        QObject::connect(socket, &QUdpSocket::readyRead, [socket, interface]() {
                            while (socket->hasPendingDatagrams()) {
                                QByteArray data;
                                data.resize(socket->pendingDatagramSize());
                                QHostAddress sender;
                                quint16 senderPort;
                                qint64 bytesRead = socket->readDatagram(
                                    data.data(), data.size(), &sender, &senderPort);
                                
                                if (bytesRead > 0) {
                                    qDebug() << "\n=== Received multicast data ===";
                                    qDebug() << "Interface:" << interface.name();
                                    qDebug() << "From:" << sender.toString() << ":" << senderPort;
                                    qDebug() << "Content:" << data;
                                    qDebug() << "Local IP:" << socket->localAddress().toString();
                                    qDebug() << "===============================\n";
                                }
                            }
                        });
                    } else {
                        qCritical() << "Join multicast FAILED on" << interface.name() 
                                   << "| Error:" << socket->errorString();
                    }
                    break; // 使用该网卡第一个有效IP
                } else {
                    qWarning() << "Bind failed on" << interface.name() 
                              << "| Error:" << socket->errorString();
                }
            }
        }
    }
}

// 发送组播数据（增强版）
void sendMulticast(const QNetworkInterface &interface, const QByteArray &data) {
    QUdpSocket socket;
    socket.setProxy(QNetworkProxy::NoProxy); // 禁用代理
    
    // 绑定到网卡的具体IP
    foreach (const QNetworkAddressEntry &entry, interface.addressEntries()) {
        QHostAddress ip = entry.ip();
        if (ip.protocol() == QAbstractSocket::IPv4Protocol && !ip.isNull()) {
            if (socket.bind(ip, 0, QUdpSocket::ShareAddress)) { // 端口0 = 自动选择
                qint64 sent = socket.writeDatagram(data, MULTICAST_ADDR, PORT);
                if (sent == data.size()) {
                    qDebug() << "Sent" << sent << "bytes from" << ip.toString();
                    return; // 发送成功则退出
                } else {
                    qWarning() << "Send failed on" << ip.toString() 
                              << "| Error:" << socket.errorString();
                }
            }
        }
    }
    qCritical() << "No suitable address found for sending on" << interface.name();
}

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);
    
    // 打印网络信息
    qDebug() << "=== Network Information ===";
    qDebug() << "Multicast Address:" << MULTICAST_ADDR.toString();
    qDebug() << "Port:" << PORT;
    
    setupMulticastReceivers();
    
    // 5秒后发送测试数据
    QTimer::singleShot(5000, [&]() {
        auto interfaces = getValidInterfaces();
        if (!interfaces.isEmpty()) {
            qDebug() << "\nSending test multicast...";
            sendMulticast(interfaces.first(), "Test multicast from " + 
                         QSysInfo::machineHostName().toUtf8());
        } else {
            qCritical() << "No valid interfaces found!";
        }
    });
    
    return a.exec();
}
//*/
